package cn.oyzh.fx.gui.tabs;

import cn.oyzh.common.util.StringUtil;
import cn.oyzh.fx.gui.menu.MenuItemHelper;
import cn.oyzh.fx.plus.FXStyle;
import cn.oyzh.fx.plus.controls.svg.SVGGlyph;
import cn.oyzh.fx.plus.controls.svg.SVGLabel;
import cn.oyzh.fx.plus.controls.tab.FXTab;
import cn.oyzh.fx.plus.ext.FXMLLoaderExt;
import cn.oyzh.fx.plus.menu.FXMenuItem;
import cn.oyzh.fx.plus.util.FXUtil;
import javafx.collections.ObservableList;
import javafx.event.Event;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Tab;
import javafx.scene.paint.Paint;

import java.util.ArrayList;
import java.util.List;

/**
 * 动态tab
 *
 * @author oyzh
 * @since 2023/11/03
 */
public abstract class RichTab extends FXTab {

    public RichTab() {
        // 加载内容
        this.loadContent();
        this.setClosable(true);
    }

    /**
     * 加载内容
     */
    protected void loadContent() {
        String url = this.url();
        if (url != null) {
            FXMLLoaderExt loaderExt = new FXMLLoaderExt();
            // 加载内容
            Node content = loaderExt.load(url);
            // 添加默认样式
            if (content instanceof Parent parent) {
                parent.getStylesheets().add(FXStyle.FX_BASE);
            }
            this.setContent(content);
            RichTabController controller = loaderExt.getController();
            this.setProp("_controller", controller);
            controller.onTabInit(this);
//            this.setOnClosed(e -> controller.onTabClose(this, e));
//            this.setOnCloseRequest(e -> controller.onCloseRequest(this, e));
        }
    }

    protected RichTabController controller() {
        return this.getProp("_controller");
    }

    /**
     * 获取tab内容地址
     *
     * @return tab内容地址
     */
    protected String url() {
        return null;
    }

    /**
     * 重载tab
     */
    public void reload() {
    }

    /**
     * 刷新tab
     */
    public void flush() {
        FXUtil.runWait(() -> {
            this.flushGraphic();
            this.flushGraphicColor();
            this.flushTitle();
        });
    }

    /**
     * 获取标题
     *
     * @return 标题
     */
    public String getTitle() {
        return this.getText();
    }

    /**
     * 设置标题
     *
     * @param title 标题
     */
    public void setTitle(String title) {
        FXUtil.runWait(() -> {
            this.setText(title);
            this.setTipText(title);
            Node node = this.getGraphic();
            if (node instanceof SVGGlyph glyph) {
                glyph.setTipText(title);
            } else if (node instanceof SVGLabel label) {
                label.setTipText(title);
            }
        });
    }

    /**
     * 设置图标
     *
     * @param graphic 图标
     */
    protected void graphic(Node graphic) {
        FXUtil.runWait(() -> this.setGraphic(graphic));
    }

    /**
     * 设置颜色
     *
     * @param paint 颜色
     */
    protected void fill(Paint paint) {
        FXUtil.runWait(() -> {
            Node node = this.getGraphic();
            if (node instanceof SVGGlyph glyph) {
                glyph.setColor(paint);
            } else if (node instanceof SVGLabel label) {
                label.setColor(paint);
                label.setTextFill(paint);
            }
        });
    }

    @Override
    public List<MenuItem> getMenuItems() {
        List<MenuItem> items = new ArrayList<>();
        FXMenuItem closeTab = MenuItemHelper.closeCurrTab(this::closeTab);
        FXMenuItem closeLeftTab = MenuItemHelper.closeLeftTab(this::closeLeftTab);
        FXMenuItem closeRightTab = MenuItemHelper.closeRightTab(this::closeRightTab);
        FXMenuItem closeOtherTab = MenuItemHelper.closeOtherTab(this::closeOtherTab);
        FXMenuItem closeAllTab = MenuItemHelper.closeAllTab(this::closeAllTab);
        items.add(closeTab);
        items.add(closeLeftTab);
        items.add(closeRightTab);
        items.add(closeOtherTab);
        items.add(closeAllTab);
        return items;
    }

    /**
     * 关闭左侧tab
     */
    public void closeLeftTab() {
        FXUtil.runLater(() -> {
            List<Tab> list = new ArrayList<>();
            for (Tab tab : this.tabs()) {
                if (tab == this) {
                    break;
                }
                list.add(tab);
            }
            this.tabs().removeAll(list);
        });
    }

    /**
     * 关闭右侧tab
     */
    public void closeRightTab() {
        FXUtil.runLater(() -> {
            List<Tab> list = new ArrayList<>();
            boolean start = false;
            for (Tab tab : this.tabs()) {
                if (tab == this) {
                    start = true;
                } else if (start) {
                    list.add(tab);
                }
            }
            this.tabs().removeAll(list);
        });
    }

    /**
     * 关闭全部tab
     */
    public void closeAllTab() {
        FXUtil.runLater(() -> this.tabs().clear());
    }

    /**
     * 关闭其他tab
     */
    public void closeOtherTab() {
        FXUtil.runLater(() -> this.tabs().removeIf(tab -> tab != this));
    }

    /**
     * 获取tab列表
     *
     * @return tab列表
     */
    protected ObservableList<Tab> tabs() {
        return this.getTabPane().getTabs();
    }

    @Override
    public void flushTitle() {
        String title1 = this.getTitle();
        String title2 = this.getTabTitle();
        if (StringUtil.notEquals(title1, title2)) {
            this.setTitle(title2);
        }
        super.flushTitle();
    }

    protected String getTabTitle() {
        return null;
    }

    @Override
    protected void onTabClosed(Event event) {
        RichTabController controller = this.controller();
        if (controller != null) {
            controller.onTabClosed(event);
        }
    }

    @Override
    protected void onTabCloseRequest(Event event) {
        RichTabController controller = this.controller();
        if (controller != null) {
            controller.onTabCloseRequest(event);
        }
    }
}
